package cn.silver.module.system.service.impl;

import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.util.ObjectUtil;
import cn.silver.framework.core.constant.CacheNames;
import cn.silver.framework.core.exception.AuthException;
import cn.silver.framework.core.utils.MapstructUtils;
import cn.silver.framework.mybatis.service.impl.DataServiceImpl;
import cn.silver.framework.satoken.utils.LoginHelper;
import cn.silver.module.system.bean.UserBean;
import cn.silver.module.system.domain.SysUser;
import cn.silver.module.system.domain.SysUserPost;
import cn.silver.module.system.domain.SysUserRole;
import cn.silver.module.system.mapper.SysUserMapper;
import cn.silver.module.system.param.PasswordParam;
import cn.silver.module.system.param.UserParam;
import cn.silver.module.system.service.ISysUserPostService;
import cn.silver.module.system.service.ISysUserRoleService;
import cn.silver.module.system.service.ISysUserService;
import cn.silver.module.system.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;

/**
 * 用户 业务层处理
 *
 * @author Silver Zhou
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysUserServiceImpl extends DataServiceImpl<SysUserMapper, SysUser, UserParam, UserBean> implements ISysUserService, UserService {

    private static final String DEFAULT_PASSWORD = "123456";
    private final ISysUserRoleService userRoleMapper;
    private final ISysUserPostService userPostMapper;

    @Override
    public String init() {
        SysUser user = this.baseMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getCode, "sysadmin"));
        if (user == null) {
            user = SysUser.getSysadmin();
            user.setPassword(BCrypt.hashpw(user.getCode() + "@" + DEFAULT_PASSWORD));
            this.baseMapper.insert(user);
        }
        return user.getId();
    }

    /**
     * 通过用户名查询用户
     *
     * @param userName 用户名
     * @return 用户对象信息
     */
    @Override
    public UserBean selectUserByUserName(String userName) {
        return baseMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getCode, userName));
    }

    /**
     * 通过手机号查询用户
     *
     * @param mobile 手机号
     * @return 用户对象信息
     */
    @Override
    public UserBean selectUserByMobile(String mobile) {
        return baseMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getMobile, mobile));
    }

    /**
     * 校验用户名称是否唯一
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    public boolean checkUserNameUnique(UserParam user) {
        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getCode, user.getCode())
                .ne(ObjectUtil.isNotNull(user.getIds()), SysUser::getId, user.getId()));
        return !exist;
    }

    /**
     * 校验手机号码是否唯一
     *
     * @param user 用户信息
     */
    @Override
    public boolean checkPhoneUnique(UserParam user) {
        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getMobile, user.getMobile())
                .ne(ObjectUtil.isNotNull(user.getId()), SysUser::getId, user.getId()));
        return !exist;
    }

    /**
     * 校验email是否唯一
     *
     * @param user 用户信息
     */
    @Override
    public boolean checkEmailUnique(UserParam user) {
        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getEmail, user.getEmail())
                .ne(ObjectUtil.isNotNull(user.getId()), SysUser::getId, user.getId()));
        return !exist;
    }

    /**
     * 注册用户信息
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    public boolean registerUser(UserParam user, String tenantId) {
//		user.setCreateBy(user.getUserId());
//		user.setUpdateBy(user.getUserId());
        SysUser sysUser = MapstructUtils.convert(user, SysUser.class);
//		sysUser.setId(tenantId);
        return baseMapper.insert(sysUser) > 0;
    }

//	/**
//	 * 用户授权角色
//	 *
//	 * @param userId  用户ID
//	 * @param roleIds 角色组
//	 */
//	@Override
//	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
//	public void insertUserAuth(String userId, String[] roleIds) {
//		insertUserRole(userId, roleIds, true);
//	}

    /**
     * 修改用户状态
     *
     * @param userId 用户ID
     * @param status 帐号状态
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public int updateUserStatus(String userId, String status) {
        return baseMapper.update(null,
                new LambdaUpdateWrapper<SysUser>()
                        .set(SysUser::getStatus, status)
                        .eq(SysUser::getId, userId));
    }

    /**
     * 修改用户基本信息
     *
     * @param user 用户信息
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public int updateUserProfile(UserParam user) {
        return baseMapper.update(null,
                new LambdaUpdateWrapper<SysUser>()
                        .set(ObjectUtil.isNotNull(user.getName()), SysUser::getName, user.getName())
                        .set(SysUser::getMobile, user.getMobile())
                        .set(SysUser::getEmail, user.getEmail())
//                        .set(SysUser::getSex, user.getSex())
                        .eq(SysUser::getId, user.getId()));
    }

    /**
     * 修改用户头像
     *
     * @param userId 用户ID
     * @param avatar 头像地址
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public boolean updateUserAvatar(String userId, String avatar) {
        return baseMapper.update(null, new LambdaUpdateWrapper<SysUser>().set(SysUser::getAvatar, avatar)
                .eq(SysUser::getId, userId)) > 0;
    }

    /**
     * 重置用户密码
     *
     * @param userIds 用户ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void resetUserPwd(Collection<String> userIds) {
        List<SysUser> users = this.baseMapper.selectBatchIds(userIds);
        for (SysUser user : users) {
            user.setPassword(BCrypt.hashpw(user.getCode() + "@" + DEFAULT_PASSWORD));
        }
        baseMapper.updateBatchById(users);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updatePwd(PasswordParam param) {
        if (StringUtils.isBlank(param.getOldPassword())) {
            throw new AuthException("旧密码不能为空");
        }
        SysUser user = this.baseMapper.selectById(LoginHelper.getUserId());
        if (!BCrypt.checkpw(param.getOldPassword(), user.getPassword())) {
            throw new AuthException("旧密码不正确");
        }
        if (!BCrypt.checkpw(param.getNewPassword(), user.getPassword())) {
            throw new AuthException("旧密码不能和新密码一样");
        }
        this.baseMapper.update(new LambdaUpdateWrapper<SysUser>().set(SysUser::getPassword, BCrypt.hashpw(param.getNewPassword())).eq(SysUser::getId, user.getId()));
    }

    /**
     * 通过用户ID删除用户
     *
     * @param userId 用户ID
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public boolean delete(String userId) {
        // 删除用户与角色关联
        userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
        // 删除用户与岗位表
        userPostMapper.delete(new LambdaQueryWrapper<SysUserPost>().eq(SysUserPost::getUserId, userId));
        return SqlHelper.retBool(baseMapper.deleteById(userId));
    }

    /**
     * 批量删除用户信息
     *
     * @param ids 需要删除的用户ID
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public boolean deleteBatch(Collection<String> ids) {
        if (LoginHelper.isSuperAdmin()) {

        }
        List<SysUser> users = this.baseMapper.selectBatchIds(ids);
//        for (String userId : ids) {
//            checkUserAllowed(userId);
//            checkUserDataScope(userId);
//        }
        // 删除用户与角色关联
        userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().in(SysUserRole::getUserId, ids));
        // 删除用户与岗位表
        userPostMapper.delete(new LambdaQueryWrapper<SysUserPost>().in(SysUserPost::getUserId, ids));
        // 防止更新失败导致的数据删除
        return SqlHelper.retBool(baseMapper.deleteByIds(ids));
    }


    @Override
    @Cacheable(cacheNames = CacheNames.SYS_USER_NAME, key = "#userId")
    public String selectUserNameById(String userId) {
        SysUser sysUser = baseMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                .select(SysUser::getCode).eq(SysUser::getId, userId));
        return ObjectUtil.isNull(sysUser) ? null : sysUser.getCode();
    }
}
